package vo

import (
	"database/sql"
	"database/sql/driver"
	"encoding/json"
	"strings"

	"github.com/spf13/cast"
)

func NewEnum[V ~int](val V) *Enum[V] {
	return &Enum[V]{val: val}
}

var (
	_ sql.Scanner      = (*Enum[int])(nil)
	_ driver.Valuer    = (*Enum[int])(nil)
	_ json.Unmarshaler = (*Enum[int])(nil)
	_ json.Marshaler   = (*Enum[int])(nil)
)

type Enum[V ~int] struct {
	val V
}

func (e Enum[V]) Get() V {
	return e.val
}

func (e *Enum[V]) Scan(src interface{}) error {
	e.val = V(cast.ToInt(strings.Trim(cast.ToString(src), "\"")))
	return nil
}

func (e Enum[V]) Value() (driver.Value, error) {
	return driver.Int32.ConvertValue(e.val)
}

func (e *Enum[V]) UnmarshalJSON(data []byte) error {
	strval := string(data)
	strval = strings.Trim(strval, "\"")
	e.val = V(cast.ToInt(strval))
	return nil
}

func (e Enum[V]) MarshalJSON() ([]byte, error) {
	return json.Marshal(e.val)
}
